﻿Public Class frmVoucherPost

    Private m_voucherNumber As Integer '本期间凭证总数
    Private m_unCheckVoucherNumber As Integer '本期间未审核凭证数量
    Private m_unPostVoucherNumber As Integer '本期间未过账凭证数量
    Private m_CreditEqualDebit As Boolean '期间凭证借贷总数是否相等

    Private m_unPostVoucherList As List(Of ClsTVoucher) = New List(Of ClsTVoucher)()


    '窗体调用主窗体显示过程
    Private Delegate Sub SetMainShowInfo(ByVal info As String)
    Private m_showInfoInMainForm As SetMainShowInfo = New SetMainShowInfo(AddressOf SetMessageToMianForm)

    '窗体其他加载过程委托
    Private Delegate Sub PostDone()
    Private m_postDone As PostDone = New PostDone(AddressOf PostDoneSub)

    ''' <summary>
    ''' 过账完毕，处理窗体界面
    ''' </summary>
    Private Sub PostDoneSub()
        '过账完毕，恢复控件状态
        m_unPostVoucherNumber = 0
        Me.txtUnPostedNumber.Text = "0"
        '没有凭证
        btnPost.Enabled = False
        btnSettle.Enabled = True
        btnClose.Enabled = True
    End Sub


    ''' <summary>
    ''' 在MDI主窗体上显示信息
    ''' </summary>
    ''' <param name="info"></param>
    Private Sub SetMessageToMianForm(ByVal info As String)
        sysFrmMdiMain.SetNotifyText(info)
    End Sub

    Private Sub frmVoucherPost_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        '会计期间
        Me.txtWorkPeriod.Text = sysCurrentLedgerSetting.LedgerWorkYear

        '显示状态
        sysFrmMdiMain.SetNotifyText("正在加载本期凭证数据...")

        '禁用按钮
        Me.btnPost.Enabled = False
        Me.btnSettle.Enabled = False
        Me.btnClose.Enabled = False

        '初始值
        m_voucherNumber = 0
        m_unCheckVoucherNumber = 0
        m_unPostVoucherNumber = 0
        m_CreditEqualDebit = True

        '加载数据
        Dim t As Threading.Thread = New Threading.Thread(AddressOf LoadDataFromDb)
        t.Start()
        '恢复控件状态
    End Sub

    Private Delegate Sub LoadDoneCallBack(ByVal isDone As Boolean)
    Private m_loadCallBack As New LoadDoneCallBack(AddressOf LoadDataDone)

    Private Sub LoadDataFromDb()
        Dim tmpDone As Boolean = False
        Dim tmpVDb As ClsTVoucherDbAccess = New ClsTVoucherDbAccess(sysUserDataConnectionString)
        Dim tmpVDict As Dictionary(Of String, Integer) = New Dictionary(Of String, Integer)()
        Dim tmpVDetailDb As ClsTVoucherDetailDbAccess = New ClsTVoucherDetailDbAccess(sysUserDataConnectionString)
        Dim tmpVDList As List(Of ClsTVoucherDetail) = New List(Of ClsTVoucherDetail)()
        Dim tmpSumCredit As Decimal
        Dim tmpSumDebit As Decimal

        Try

            '取本期凭证数量
            m_voucherNumber = tmpVDb.GetVoucherCountInWorkPeriod(sysCurrentLedgerSetting.LedgerWorkYear)
            If m_voucherNumber > 0 Then
                '取借贷值
                tmpSumCredit = tmpVDb.GetCreditSumInWorkPeriod(sysCurrentLedgerSetting.LedgerWorkYear)
                tmpSumDebit = tmpVDb.GetDebitSumInWorkPeriod(sysCurrentLedgerSetting.LedgerWorkYear)

                If tmpSumCredit = tmpSumDebit Then
                    m_CreditEqualDebit = True
                Else
                    m_CreditEqualDebit = False
                End If

                m_unCheckVoucherNumber = tmpVDb.GetUnCheckedCountInWorkPeriod(sysCurrentLedgerSetting.LedgerWorkYear)
                m_unPostVoucherNumber = tmpVDb.GetUnPostedCountInWorkPeriod(sysCurrentLedgerSetting.LedgerWorkYear)
            End If

            '如果未过账数量大于0，则取出未过账凭证集合
            If m_unPostVoucherNumber > 0 Then
                '取出未过账凭证主体
                m_unPostVoucherList = tmpVDb.GetUnPostVoucherInWorkPeriod(sysCurrentLedgerSetting.LedgerWorkYear)
                '凭证主体索引入字典
                For Each tmpV As ClsTVoucher In m_unPostVoucherList
                    tmpVDict.Add(tmpV.VoucherGroup & tmpV.VoucherNumber, m_unPostVoucherList.IndexOf(tmpV))
                Next
                '取出本期全部的凭证分录
                tmpVDList = tmpVDetailDb.GetAllEntriesInWorkPeriod(sysCurrentLedgerSetting.LedgerWorkYear)
                For Each tmpVD As ClsTVoucherDetail In tmpVDList
                    m_unPostVoucherList(tmpVDict(tmpVD.VoucherGroup & tmpVD.VoucherNumber)).EntryList.Add(tmpVD)
                Next

                'For Each tmpV As ClsTVoucher In m_unPostVoucherList
                '    '取出分录集合
                '    tmpV.EntryList = tmpVDetailDb.GetAllEntries(tmpV.VoucherAutoId)
                'Next

            End If

            tmpDone = True
        Catch ex As Exception
            '出错
            Debug.Print(ex.Message)
        End Try

        '
        Me.Invoke(m_loadCallBack, tmpDone)

    End Sub

    Private Sub LoadDataDone(ByVal isDone As Boolean)

        '数据加载完毕
        If Not isDone Then
            MessageBox.Show("加载凭证数据时出错，请退出重试。", "加载凭证数据")
            Me.btnPost.Enabled = False
            Me.btnSettle.Enabled = False
            Me.btnClose.Enabled = True
            Return
        End If

        Me.txtVoucherNumber.Text = m_voucherNumber
        Me.txtUnCheckedNumber.Text = m_unCheckVoucherNumber
        Me.txtUnPostedNumber.Text = m_unPostVoucherNumber
        '如果没有凭证，则无凭证结账可用
        If m_voucherNumber > 0 Then
            Me.chkNoVoucher.Enabled = False
        Else
            Me.chkNoVoucher.Checked = True
            Me.chkNoVoucher.Enabled = True
        End If

        'Me.chkNoVoucher.Checked = (m_voucherNumber = 0)
        '借贷平衡,不管是否平衡，则都不可用
        Me.chkCreditDebitBalance.Checked = m_CreditEqualDebit
        Me.chkCreditDebitBalance.Enabled = False

        '按钮状态
        If m_voucherNumber = 0 Then
            '没有凭证
            btnPost.Enabled = False
            btnSettle.Enabled = True
            btnClose.Enabled = True
            Return
        End If

        If Not m_CreditEqualDebit Then
            '借贷不平衡，
            btnPost.Enabled = False
            btnSettle.Enabled = False
            btnClose.Enabled = True
            Return
        End If

        If m_unCheckVoucherNumber > 0 Then
            '有未审核凭证
            btnPost.Enabled = False
            btnSettle.Enabled = False
            btnClose.Enabled = True
            Return
        End If


        '有凭证，判断是否可以过账
        If m_unPostVoucherNumber > 0 Then
            '有未过账凭证
            btnPost.Enabled = True
            btnSettle.Enabled = False
            btnClose.Enabled = True
        Else
            '没有未过账凭证，可以结账
            btnPost.Enabled = False
            btnSettle.Enabled = True
            btnClose.Enabled = True
        End If

        sysFrmMdiMain.SetNotifyText("就绪")

    End Sub

    Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
        Me.Close()

    End Sub

    Private Sub btnPost_Click(sender As Object, e As EventArgs) Handles btnPost.Click
        '凭证过账
        Me.btnPost.Enabled = False
        Me.btnSettle.Enabled = False
        Me.btnClose.Enabled = False

        sysFrmMdiMain.SetNotifyText("正在准备记账数据...")
        Dim t As Threading.Thread = New Threading.Thread(AddressOf PostVoucher)
        t.Start()
    End Sub

    Private m_dbIntransition As Boolean = False '当下是否在事务中

    ''' <summary>
    ''' 后台记账过程
    ''' </summary>
    Private Sub PostVoucher()

        'Dim tmpBeginTime As DateTime = Now()
        'Debug.Print("过账开始：" & tmpBeginTime.ToLongTimeString)

        sysFrmMdiMain.Invoke(m_showInfoInMainForm, New Object() {"同步总账及余额表科目信息..."})

        '第一步，同步科目到总账数据表中
        '1、取出全部科目
        Dim tmpAcctDb As ClsTAccountDbAccess = New ClsTAccountDbAccess(sysUserDataConnectionString)

        '开启事务
        If tmpAcctDb.GetConnection().BeginTransaction() Then
            m_dbIntransition = True
        Else
            '不能开启事务
            MessageBox.Show("数据事务无法开启，过账失败。请重试。", "凭证过账")
            Return
        End If

        '取出全部科目，准备同步总账科目
        Dim tmpAcctList As List(Of ClsTAccount) = tmpAcctDb.GetAllRecords(Of ClsTAccount)()

        '2、取出本期总账数据汇总表中全部科目
        Dim tmpGeneralMoneyDb As ClsTGeneralMoneyLedgerDbAccess = New ClsTGeneralMoneyLedgerDbAccess(sysUserDataConnectionString)
        '取出本期的总账余额记录
        Dim tmpGeneralMoneyList As List(Of ClsTGeneralMoneyLedger) = tmpGeneralMoneyDb.GetAllGeneralMoneyInPeriod(sysCurrentLedgerSetting.LedgerWorkYear)
        '将待查找值放入字典中,以备按科目编码查找年初数
        Dim tmpDicGeneralL As Dictionary(Of String, Decimal) = New Dictionary(Of String, Decimal)()
        For Each tmpSumA As ClsTGeneralMoneyLedger In tmpGeneralMoneyList
            tmpDicGeneralL.Add(tmpSumA.AcctCode, tmpSumA.Year)
        Next

        '3、循环查看总账数据表本期数据中是否包含该科目

        Dim tmpABdb As ClsTBalanceMoneyDbAccess = New ClsTBalanceMoneyDbAccess(sysUserDataConnectionString)
        Dim tmpAb As ClsTBalanceMoney

        'TODO:同步更新数量余额
        For Each tmpA As ClsTAccount In tmpAcctList

            '4、如果包含，则对比年初数据,是否需要更新，如不包含，则插入
            If tmpDicGeneralL.ContainsKey(tmpA.AccountCode) Then
                '4.1、包含
                If tmpA.YearMoney <> tmpDicGeneralL.Item(tmpA.AccountCode) Then
                    '不相等，则更新科目汇总表对应期间和科目的年初数据
                    If tmpGeneralMoneyDb.UpdateYear(tmpA.AccountCode, tmpDicGeneralL.Item(tmpA.AccountCode), tmpA.YearMoney) = 0 Then
                        '出错
                    End If
                    '同步更新科目余额表中的年初数
                    If tmpABdb.UpdateYearMoney(tmpA.AccountCode, tmpDicGeneralL.Item(tmpA.AccountCode), tmpA.YearMoney) = 0 Then
                        '表明余额表中没有该科目，那一定是出错了
                    End If
                End If
            Else
                '4.2不包含，则插入新值
                '取出上个期间的月末值
                Dim beginBal As Decimal
                Dim intPeriod As Integer = Integer.Parse(sysCurrentLedgerSetting.LedgerWorkYear.Substring(4, 2))
                Dim prevPeriod As String '= sysCurrentLedgerSetting.LedgerWorkYear.Substring(0, 4)
                Dim tmpPrevGeneralLedger As ClsTGeneralMoneyLedger

                '取年初数做期初数
                beginBal = tmpA.YearMoney

                If intPeriod > 1 Then
                    '取出上个期间
                    intPeriod -= 1 ' Integer.Parse(sysCurrentLedgerSetting.LedgerWorkYear.Substring(4, 2))
                    prevPeriod = sysCurrentLedgerSetting.LedgerWorkYear.Substring(0, 4)
                    prevPeriod &= intPeriod.ToString("D2")
                    '取上个期间该科目的期末余额
                    tmpPrevGeneralLedger = tmpGeneralMoneyDb.GetGeneralMoneyInPeriodByAcct(prevPeriod, tmpA.AccountCode)

                    '如果上个期间没有值 ，可能因为启用期间大于1。
                    '如果找到，则使用上期间的期末值为
                    If tmpPrevGeneralLedger IsNot Nothing Then
                        beginBal = tmpPrevGeneralLedger.Balance
                    End If

                End If

                '如果有，则复制生成本期间
                '如果没有，则生成一个新的总账数据对象插入
                Dim tmpNewSumAcct As ClsTGeneralMoneyLedger = New ClsTGeneralMoneyLedger()
                With tmpNewSumAcct
                    .GeneralId = 0
                    .WorkPeriod = sysCurrentLedgerSetting.LedgerWorkYear
                    .AcctCode = tmpA.AccountCode
                    .AcctLevel = tmpA.Level
                    .IfLastLevel = tmpA.IfLastLevel
                    .AcctName = tmpA.AccountName
                    .Year = tmpA.YearMoney '年初数
                    .BeginBalance = beginBal '此处应该是上月数据，期初数
                    .CreditSum = 0
                    .CreditTotal = 0
                    .DebitSum = 0
                    .DebitTotal = 0
                    .Balance = beginBal '此处应该是上月数据，期末数，但第一笔应该是上月月末数，即本月期初数
                    .BalanceDirection = tmpA.BalanceDirection
                End With
                Dim tmpRetInt As Integer = tmpGeneralMoneyDb.InsertGeneralMoney(tmpNewSumAcct)
                If tmpRetInt <> 0 Then
                    tmpNewSumAcct.GeneralId = tmpRetInt
                End If

                '4.3、此处判断年初数是否为0，如果不为0则插入余额表数据
                If tmpA.YearMoney <> 0 Then
                    '插入新的科目余额数据，要保证余额表数据准确，即包含没有发生额但有年初数的科目
                    tmpAb = New ClsTBalanceMoney()
                    With tmpAb
                        .BalanceId = 0
                        .WorkPeriod = tmpNewSumAcct.WorkPeriod
                        .AcctCode = tmpNewSumAcct.AcctCode
                        .AcctLevel = tmpNewSumAcct.AcctLevel
                        .IfLastLevel = tmpNewSumAcct.IfLastLevel
                        .AcctName = tmpA.FullName
                        .Year = tmpNewSumAcct.Year
                        .BeginBalance = tmpNewSumAcct.BeginBalance
                        .CreditSum = tmpNewSumAcct.CreditSum
                        .CreditTotal = tmpNewSumAcct.CreditTotal
                        .DebitSum = tmpNewSumAcct.DebitSum
                        .DebitTotal = tmpNewSumAcct.DebitTotal
                        .Balance = tmpNewSumAcct.Balance
                        .BalanceDirection = tmpNewSumAcct.BalanceDirection
                    End With

                    tmpAb.BalanceId = tmpABdb.InsertBalanceMoney(tmpAb)
                End If

            End If
        Next
        '

        '此处需要提交前面的结果 。
        tmpAcctDb.GetConnection.CompleteTransaction()

        'Dim tmpD1 As DateTime = Now()
        'Debug.Print("同步总账及余额表科目数据，共花:" & (tmpD1 - tmpBeginTime).TotalSeconds)
        sysFrmMdiMain.Invoke(m_showInfoInMainForm, New Object() {"凭证分录数据汇总写入..."})

        '此处要重新打开事务
        tmpAcctDb.GetConnection().BeginTransaction()

        '第二步，取出每一个分录进行记账
        '处理凭证过账标记
        Dim tmpVDb As ClsTVoucherDbAccess = New ClsTVoucherDbAccess(sysUserDataConnectionString)
        tmpVDb.PostVoucher(m_unPostVoucherList, True)
        '处理凭证的所有分录数据过账
        For Each tmpV As ClsTVoucher In m_unPostVoucherList
            '分录数据过账
            For Each tmpVd As ClsTVoucherDetail In tmpV.EntryList
                '临时余额数据返回
                Dim tmpAcctBalance As ClsTBalanceMoney = PostOneEntry(tmpVd, tmpVd.AccountCode)
                If tmpAcctBalance Is Nothing Then
                    MessageBox.Show("数据事务无法开启，过账失败。请重试。", "凭证过账")
                    tmpAcctDb.GetConnection().RollBackTransaction()
                    Return
                End If

                '更新三栏账
                Dim tmpTDRDb As ClsTDetailReportDbAccess = New ClsTDetailReportDbAccess(sysUserDataConnectionString)
                Dim tmpClsTDR As ClsTDetailReport = New ClsTDetailReport()
                With tmpClsTDR
                    .DetailReportId = 0 'Integer
                    .WorkPeriod = sysCurrentLedgerSetting.LedgerWorkYear  'String
                    .AcctCode = tmpVd.AccountCode   'String
                    .AcctLevel = tmpAcctBalance.AcctLevel  'Integer
                    .AcctFullName = tmpVd.AccountCodeName  'String
                    .VoucherId = tmpVd.VoucherId  'Integer
                    .VoucherGroupId = tmpVd.VoucherGroupId  'Integer
                    .VoucherGroupShorName = tmpVd.VoucherGroup  'String
                    .VoucherNumber = tmpVd.VoucherNumber  'Integer
                    .Exp = tmpVd.Excerpta  'String
                    .Credit = tmpVd.Credit  'Decimal
                    .Debit = tmpVd.Debit  'Decimal
                    .BeginBalance = tmpAcctBalance.BeginBalance  'Decimal
                    .EndBalance = tmpAcctBalance.Balance  'Decimal
                    .BalanceDirection = tmpAcctBalance.BalanceDirection  'String
                End With
                tmpClsTDR.DetailReportId = tmpClsTDR.DetailReportId = tmpTDRDb.InsertDetailReport(tmpClsTDR)

            Next
        Next

        'Dim tmpD2 As DateTime = Now()
        'Debug.Print("分录过账，共花：" & (tmpD2 - tmpD1).TotalSeconds)
        sysFrmMdiMain.Invoke(m_showInfoInMainForm, New Object() {"过账完毕，写入会计期间数据..."})

        '将过账结果写入到会计期间表中
        '本月凭证总数量：m_voucherNumber
        Dim tmpWPDb As ClsTWorkPeriodDbAccess = New ClsTWorkPeriodDbAccess(sysUserDataConnectionString)
        Dim tmpClsWP As ClsTWorkPeriod = tmpWPDb.GetWorkPeriod(sysCurrentLedgerSetting.LedgerWorkYear)
        If tmpClsWP Is Nothing Then
            '没有找到，则插入一行新数据
            tmpClsWP = New ClsTWorkPeriod()
            With tmpClsWP
                .WorkPeriodId = 0
                .WorkPeriod = sysCurrentLedgerSetting.LedgerWorkYear
                .VoucherCount = m_voucherNumber
                .Posted = True
                .Settled = False
            End With
            tmpWPDb.InsertWorkPeriod(tmpClsWP)
        Else
            tmpClsWP.VoucherCount = m_voucherNumber
            tmpClsWP.Posted = True
            tmpWPDb.UpdateWorkPeriod(tmpClsWP)
        End If

        '第三步，结束
        '提交事务
        tmpAcctDb.GetConnection().CompleteTransaction()

        '
        sysFrmMdiMain.Invoke(m_showInfoInMainForm, New Object() {"过账完毕!"})

        Me.Invoke(m_postDone)

    End Sub

    Private m_GlaDict As Dictionary(Of String, ClsTGeneralMoneyLedger) = New Dictionary(Of String, ClsTGeneralMoneyLedger)()
    Private m_AsumDict As Dictionary(Of String, ClsTAccountSum) = New Dictionary(Of String, ClsTAccountSum)()
    Private m_AcctDict As Dictionary(Of String, ClsTAccount) = New Dictionary(Of String, ClsTAccount)()
    Private m_BalMoneyDict As Dictionary(Of String, ClsTBalanceMoney) = New Dictionary(Of String, ClsTBalanceMoney)()

    ''' <summary>
    ''' 登录一条分录数据到科目汇总表中
    ''' </summary>
    ''' <param name="en"></param>
    ''' <returns></returns>
    Private Function PostOneEntry(ByVal en As ClsTVoucherDetail, ByVal acctCode As String) As ClsTBalanceMoney

        '1、取出指定科目的总账数据
        Dim tmpGLDb As ClsTGeneralMoneyLedgerDbAccess = New ClsTGeneralMoneyLedgerDbAccess(sysUserDataConnectionString)
        Dim tmpGlAcct As ClsTGeneralMoneyLedger '= tmpGLDb.GetGeneralMoneyInPeriodByAcct(sysCurrentLedgerSetting.LedgerWorkYear, acctCode)

        '取得全部科目的总账数据，并写入字典中
        If m_GlaDict.Count < 1 Then
            '取出当前所有
            Dim tmpGlaList As List(Of ClsTGeneralMoneyLedger) = tmpGLDb.GetAllGeneralMoneyInPeriod(sysCurrentLedgerSetting.LedgerWorkYear)
            For Each tmpGLA As ClsTGeneralMoneyLedger In tmpGlaList
                m_GlaDict.Add(tmpGLA.AcctCode, tmpGLA)
            Next
        End If
        tmpGlAcct = m_GlaDict(acctCode)

        '2、计算指定科目的借、贷以及余额
        tmpGlAcct.CreditSum += en.Credit '贷方发生
        tmpGlAcct.DebitSum += en.Debit '借方发生
        tmpGlAcct.CreditTotal += en.Credit '贷方累计
        tmpGlAcct.DebitTotal += en.Debit '借方累计

        Dim tmpBal As Decimal = en.Debit - en.Credit '借 - 贷
        If tmpGlAcct.BalanceDirection = "贷方" Then
            '余额为 贷 - 借
            tmpBal *= -1
        End If
        tmpGlAcct.Balance += tmpBal '余额

        '3、更新科目借、贷及余额数据
        If tmpGLDb.UpdateGeneralMoney(tmpGlAcct) = 0 Then
            '出错
            Return Nothing
        End If

        '4、更新科目汇总数据

        '取出当前指定科目的汇总数据
        Dim tmpASDb As ClsTAccountSumDbAccess = New ClsTAccountSumDbAccess(sysUserDataConnectionString)
        Dim tmpAS As ClsTAccountSum = Nothing '= tmpASDb.GetAccountSumInPeriod(sysCurrentLedgerSetting.LedgerWorkYear, acctCode)

        '取出全部科目汇总数据
        If m_AsumDict.Count < 1 Then
            Dim tmpAsList As List(Of ClsTAccountSum) = tmpASDb.GetAllAccountSumInPeriod(sysCurrentLedgerSetting.LedgerWorkYear)
            For Each itemAs As ClsTAccountSum In tmpAsList
                m_AsumDict.Add(itemAs.AcctCode, itemAs)
            Next
        End If
        '取出指定科目汇总数据
        If m_AsumDict.ContainsKey(acctCode) Then
            tmpAS = m_AsumDict(acctCode)
        End If

        '取出当前指定科目的科目数据
        Dim tmpADb As ClsTAccountDbAccess = New ClsTAccountDbAccess(sysUserDataConnectionString)
        Dim tmpA As ClsTAccount = Nothing  '= tmpADb.GetAccountByCode(acctCode)

        '取出全部科目
        If m_AcctDict.Count < 1 Then
            Dim tmpAcctList As List(Of ClsTAccount) = tmpADb.GetAllRecords(Of ClsTAccount)
            For Each itemA As ClsTAccount In tmpAcctList
                m_AcctDict.Add(itemA.AccountCode, itemA)
            Next
        End If
        tmpA = m_AcctDict(acctCode)

        '如果没有科目汇总数据，说明当前科目是本月第一次写入
        If tmpAS Is Nothing Then
            tmpAS = New ClsTAccountSum()
            With tmpAS
                .AcctSumId = 0
                .WorkPeriod = sysCurrentLedgerSetting.LedgerWorkYear
                .AcctCode = acctCode
                .AcctLevel = tmpA.Level
                .IfLastLevel = tmpA.IfLastLevel
                .AcctName = tmpA.AccountName
                .CreditSum = 0
                .DebitSum = 0
            End With
            tmpAS.AcctSumId = tmpASDb.InsertAccountSum(tmpAS)

            '添加到字典中
            m_AsumDict.Add(acctCode, tmpAS)
        End If

        '本月借贷数据累加
        tmpAS.CreditSum += en.Credit
        tmpAS.DebitSum += en.Debit
        '更新科目汇总数据
        If tmpASDb.UpdateAccountSum(tmpAS) = 0 Then
            '出错
            Return Nothing
        End If

        'TODO:更新数量汇总数据 外币汇总数据

        '5、更新科目余额数据
        '取出指定科目的余额数据
        Dim tmpABDb As ClsTBalanceMoneyDbAccess = New ClsTBalanceMoneyDbAccess(sysUserDataConnectionString)
        Dim tmpAB As ClsTBalanceMoney = Nothing '= tmpABDb.GetAcctBalanceMoneyInPeriodByAcct(sysCurrentLedgerSetting.LedgerWorkYear, acctCode)

        '取出全部
        If m_BalMoneyDict.Count < 1 Then
            Dim tmpBMList As List(Of ClsTBalanceMoney) = tmpABDb.GetAcctBalanceMoneyInPeriod(sysCurrentLedgerSetting.LedgerWorkYear)
            For Each itemBal As ClsTBalanceMoney In tmpBMList
                m_BalMoneyDict.Add(itemBal.AcctCode, itemBal)
            Next
        End If
        If m_BalMoneyDict.ContainsKey(acctCode) Then
            tmpAB = m_BalMoneyDict(acctCode)
        End If

        '如果当前期间没有指定的余额数据，说明是第一次写入本月余额，使用总账数据写入
        If tmpAB Is Nothing Then
            '插入一条新的科目余额数据
            tmpAB = New ClsTBalanceMoney()
            With tmpAB

                .BalanceId = 0
                .WorkPeriod = sysCurrentLedgerSetting.LedgerWorkYear
                .AcctCode = acctCode
                .AcctLevel = tmpA.Level
                .IfLastLevel = tmpA.IfLastLevel
                .AcctName = tmpA.AccountName
                .Year = tmpA.YearMoney
                .BeginBalance = tmpGlAcct.BeginBalance  'tmpA.YearMoney
                .CreditSum = 0
                .CreditTotal = 0
                .DebitSum = 0
                .DebitTotal = 0
                .Balance = tmpGlAcct.Balance  'tmpA.YearMoney
                .BalanceDirection = tmpA.BalanceDirection

            End With

            '插入新的科目余额数据
            tmpAB.BalanceId = tmpABDb.InsertBalanceMoney(tmpAB)

            '添加到字典中
            m_BalMoneyDict.Add(acctCode, tmpAB)

        End If

        '使用总账数据进行更新
        With tmpAB
            .BeginBalance = tmpGlAcct.BeginBalance  'tmpA.YearMoney
            .CreditSum = tmpGlAcct.CreditSum
            .CreditTotal = tmpGlAcct.CreditTotal
            .DebitSum = tmpGlAcct.DebitSum
            .DebitTotal = tmpGlAcct.DebitTotal
            .Balance = tmpGlAcct.Balance  'tmpA.YearMoney
        End With

        tmpABDb.UpdateBalanceMoney(tmpAB)

        '7、递归更新科目上级数据
        If tmpA.Level > 1 Then
            PostOneEntry(en, tmpA.PrevLevelCode)
        End If

        '结束 提交
        Return tmpAB

    End Function

    Private Sub btnSettle_Click(sender As Object, e As EventArgs) Handles btnSettle.Click
        '判断是否可以结账
        If m_unPostVoucherNumber > 0 Then
            MessageBox.Show("当前会计期间有未过账凭证，请过账后再试。", "期间结账")
            Return
        End If
        '本期间结账
        '第一步：取出当前会计参数中的会计期间
        Dim tmpWorkYear As String = sysCurrentLedgerSetting.LedgerWorkYear.Substring(0, 4)
        Dim tmpWorkMonth As Integer = CInt(sysCurrentLedgerSetting.LedgerWorkYear.Substring(4))
        Dim tmpNextWorkMonth As Integer
        tmpNextWorkMonth = tmpWorkMonth + 1
        If tmpNextWorkMonth > 12 Then
            tmpNextWorkMonth = 12
        End If
        Dim tmpNextWorkPeriod As String = tmpWorkYear & tmpNextWorkMonth.ToString("D2")

        '第二步：更新会计期间表及当前会计参数中的会计期间
        Dim tmpWPDb As ClsTWorkPeriodDbAccess = New ClsTWorkPeriodDbAccess(sysUserDataConnectionString)
        If tmpWPDb.SettleWorkPeriod(sysCurrentLedgerSetting.LedgerWorkYear, True) = 0 Then
            '出错，退出
            MessageBox.Show("当前会计期间结账时出现错误。请稍后再试。", "期间结账")
            Return
        End If
        Dim tmpLSDb As ClsTLedgerSettingDbAccess = New ClsTLedgerSettingDbAccess(sysUserDataConnectionString)
        If tmpNextWorkMonth > tmpWorkMonth Then
            sysCurrentLedgerSetting.LedgerWorkYear = tmpNextWorkPeriod
            If tmpLSDb.UpdateTLedgerSetting(sysCurrentLedgerSetting) = 0 Then
                '出错
                MessageBox.Show("更新当前会计期间结账信息时出现错误。请稍后再试。", "期间结账")
                Return
            End If
        End If
        '第三步：改变控件状态
        Me.btnSettle.Enabled = False
        '第四步：更改主窗体的会计期间显示
        sysFrmMdiMain.FreshWorkPeriodText()
    End Sub
End Class